package com.idea.relax.tool.core.tree;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @author azhao
 */
public class TreeUtil {
    private TreeUtil() {
    }

    private static Logger logger = LoggerFactory.getLogger(TreeUtil.class);

    public static <T> List<T> listToTree(List<T> source, Comparator<T> comparator, ErgodicStrategy ergodicStrategy) {
        ListToTree<T> listToTree = new ListToTree<>();
        TreeParam<T> treeParam = new TreeParam<>(source);
        treeParam.setComparator(comparator);
        treeParam.setErgodicStrategy(ergodicStrategy);
        return listToTree.transfer(treeParam);
    }

    public static <T> List<T> listToTree(List<T> source, ErgodicStrategy ergodicStrategy) {
        return listToTree(source, null, ergodicStrategy);
    }

    public static <T> List<T> listToTree(List<T> source, Comparator<T> comparator) {
        return listToTree(source, comparator, ErgodicStrategy.ROOT_PID_IS_NULL);
    }

    public static <T> List<T> listToTree(List<T> source) {
        return listToTree(source, null, ErgodicStrategy.ROOT_PID_IS_NULL);
    }

    public static <T> void visitTree(List<T> source, Consumer<T> consumer) {
        TreeVisit<T> treeVisit = new TreeVisit<>();
        treeVisit.visitTree(source, consumer);
    }

    public static <T> List<T> getParentsList(T t, List<T> list) {
        TreeVisit<T> treeVisit = new TreeVisit<>();
        return treeVisit.getParentsList(t, list);
    }

    public static <T> List<T> treeToList(List<T> source) {
        TreeToList<T> treeToList = new TreeToList<>();
        return treeToList.transfer(source);
    }

    public static <T> List<T> treeToList(T source) {
        TreeToList<T> treeToList = new TreeToList<>();
        return treeToList.transfer(source);
    }

    /**
     * @param t
     * @param fun 通过当前节点获取子节点
     * @param <T>
     * @return
     */
    public static <T> List<T> buildList(T t, Function<T, List<T>> fun) {
        TreeBuild<T> treeBuild = new TreeBuild<>();
        return treeBuild.buildList(t, fun);
    }

    public static <T> List<T> buildList(List<T> t, Function<T, List<T>> fun) {
        TreeBuild<T> treeBuild = new TreeBuild<>();
        return treeBuild.buildList(t, fun);
    }

}
